using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Xml;
using System.Data.SqlClient;
using Microsoft.SharedSource.SqlServer.MDDE.Middleware;
using Microsoft.SqlServer.Dts.Runtime;

namespace Microsoft.SharedSource.SqlServer.MDDE.ManagementStudio
{
    internal partial class UpgradeTemplateSelectLocation : UpgradeTemplateBase
    {
        #region Fields and enumerations

        enum TemplateLocation
        {
            FileSystem,
            SQLServer
        }

        enum ServerAuthentication
        {
            WindowsAuthentication,
            SQLServerAuthentication
        }


        #endregion

        internal UpgradeTemplateSelectLocation(UpgradeTemplateWizardController controller)
            : base(controller)
        {
            InitializeComponent();

            // Apply properties.
            this.HeaderBoldText = "Choose the new template location";
            this.HeaderRegularText = "Select the location of new template that could either be file system or sql server.";

            // Populate the authentication combobox.
            DataTable dtAuth = new DataTable();
            dtAuth.Columns.Add("Name", typeof(string));
            dtAuth.Columns.Add("Value", typeof(ServerAuthentication));
            dtAuth.Rows.Add("Windows Authentication",
                ServerAuthentication.WindowsAuthentication);
            dtAuth.Rows.Add("SQL Server Authentication",
                ServerAuthentication.SQLServerAuthentication);
            cmbAuthentication.DataSource = dtAuth;
            cmbAuthentication.ValueMember = "Value";
            cmbAuthentication.DisplayMember = "Name";
            cmbAuthentication.SelectedItem =
                ServerAuthentication.WindowsAuthentication;

            // Populate the TemplateLocation combobox.
            DataTable dtLocation = new DataTable();
            dtLocation.Columns.Add("Name", typeof(string));
            dtLocation.Columns.Add("Value", typeof(TemplateLocation));
            dtLocation.Rows.Add("File System",
                TemplateLocation.FileSystem);
            dtLocation.Rows.Add("SQL Server",
                TemplateLocation.SQLServer);
            cmbTemplateLocation.DataSource = dtLocation;
            cmbTemplateLocation.ValueMember = "Value";
            cmbTemplateLocation.DisplayMember = "Name";
            cmbTemplateLocation.SelectedItem =
                TemplateLocation.FileSystem;

        }

        #region Event handlers

        private void btnBrowse_Click(object sender, EventArgs e)
        {
            OpenFileDialog fd = new OpenFileDialog();
            fd.Title = "Import Template";
            fd.Filter = "SSIS Packages|*.dtsx";
            fd.Multiselect = false;
            fd.ShowDialog();

            Cursor.Current = Cursors.WaitCursor;
            txtTemplatePath.Text = fd.FileName;
            this.Refresh();

            Cursor.Current = Cursors.Default;
        }

        private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                e.Result = Microsoft.SqlServer.Management.Smo.
                    SmoApplication.EnumAvailableSqlServers();
            }
            catch
            {
                // Gobble up all exceptions.
                e.Result = null;
            }
        }

        /// <summary>
        ///  check whether PopulateServer was completed successfully
        ///  or whether an exception had been thrown.
        /// </summary> 
        private void backgroundWorker_RunWorkerCompleted(
            object sender, RunWorkerCompletedEventArgs e)
        {
            // Handle the case where an exception was thrown.
            // Else populate the Server combobox.
            if (e.Error != null)
            {
                MessageBox.Show(e.Error.Message, "Error",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else
            {
                cmbServer.DataSource = e.Result;
                cmbServer.DisplayMember = "Name";
                cmbServer.ValueMember = "Name";

                this.Enabled = true;

                // Change mouse cursor.
                this.Cursor = Cursors.Default;
            }

            if (cmbServer.Items.Count > 0)
                cmbServer.SelectedIndex = 0;
        }

        /// <summary>
        /// Handle the control state of available controls.
        /// </summary> 
        private void cmbAuthentication_SelectedIndexChanged(
            object sender, EventArgs e)
        {
            txtUserName.Text = String.Empty;
            txtPassward.Text = String.Empty;
            if (cmbAuthentication.SelectedValue is int
                && (ServerAuthentication)cmbAuthentication.SelectedValue ==
                ServerAuthentication.SQLServerAuthentication)
            {
                txtUserName.Enabled = true;
                txtPassward.Enabled = true;
            }
            else
            {
                txtUserName.Enabled = false;
                txtPassward.Enabled = false;
            }
        }

        private void cmbTemplateLocation_SelectedIndexChanged(object sender, EventArgs e)
        {
            txtTemplatePath.Text = String.Empty;
            cmbServer.Text = String.Empty;
            if (cmbTemplateLocation.SelectedValue is int
                && (TemplateLocation)cmbTemplateLocation.SelectedValue ==
                TemplateLocation.SQLServer)
            {
                cmbServer.Enabled = true;
                cmbAuthentication.Enabled = true;
                //txtTemplatePath.Enabled = false;
                btnBrowse.Enabled = false;
            }
            else
            {
                cmbServer.Enabled = false;
                cmbAuthentication.Enabled = false;
                //txtTemplatePath.Enabled = true;
                btnBrowse.Enabled = true;
            }
        }

        private void cmbServer_DropDown(object sender, EventArgs e)
        {
            PopulateServers();
        }

        private void cmbServer_KeyDown(object sender, KeyEventArgs e)
        {
            // If down arrow key is pressed, 
            // try populating the server list.
            if (e.KeyCode == Keys.Down)
            {
                PopulateServers();
            }
        }

        protected override void btnNext_Click(object sender, EventArgs e)
        {
            #region Add the form configurations to wizard configuration.

            XmlNode configurationRoot = controller.WizardConfigurations.FirstChild;

            if (ValidateEntries())
            {
                string connection = String.Empty;

                // Locate any earlier entry for this form.
                XmlNode formLocationInfo =
                    configurationRoot.SelectSingleNode("//Form[@Name=\"GetTemplateLocation\"]");

                // Delete the earlier node if found.
                if (formLocationInfo != null)
                    formLocationInfo.ParentNode.RemoveChild(formLocationInfo);

                // Add the 'Form' element.
                formLocationInfo =
                    UIHelper.AppendChildElement(configurationRoot, "Form",
                    new string[] { "Name", "GetTemplateLocation" });

                // Try fetching the template body.
                string templateBody = string.Empty;

                try
                {
                    switch ((TemplateLocation)cmbTemplateLocation.SelectedValue)
                    {
                        case TemplateLocation.FileSystem:
                            StreamReader rdr = new StreamReader(txtTemplatePath.Text);
                            templateBody = rdr.ReadToEnd();
                            break;
                        case TemplateLocation.SQLServer:
                            connection = PrepareConnectionString();
                            Microsoft.SqlServer.Dts.Runtime.Application app =
                                new Microsoft.SqlServer.Dts.Runtime.Application();
                            Package pkg = app.LoadFromSqlServer(
                                txtTemplatePath.Text, cmbServer.Text,
                                txtUserName.Enabled ? txtUserName.Text : null,
                                txtPassward.Enabled ? txtPassward.Text : null,
                                null);
                            pkg.SaveToXML(out templateBody, null);
                            break;
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error getting the template information.\n" + ex.Message,
                        "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                UIHelper.AppendChildElement(formLocationInfo, "UserInput",
                     new string[]{"Name","Location",
                        "Value",cmbTemplateLocation.Text});

                UIHelper.AppendChildElement(formLocationInfo, "UserInput",
                     new string[]{"Name","ConnectionString",
                        "Value",connection});

                UIHelper.AppendChildElement(formLocationInfo, "UserInput",
                     new string[]{"Name","FilePath",
                        "Value",txtTemplatePath.Text});

                UIHelper.AppendChildElement(formLocationInfo, "UserInput",
                     new string[]{"Name","NewTemplateName",
                        "Value",txtNewTemplateName.Text});

                UIHelper.AppendChildElement(formLocationInfo, "UserInput",
                     new string[]{"Name","TemplateBody",
                        "Value",templateBody});
            }
            else
                return;

            #endregion

            // Invoke the base method.
            base.btnNext_Click(sender, e);
        }

        #endregion

        #region Helper methods

        private void PopulateServers()
        {
            // Try populating the server list.
            if (cmbServer.DataSource == null)
            {
                cmbServer.Text = "Loading...";

                // Disable all controls.
                this.Enabled = false;

                // Change the cursor.
                this.Cursor = Cursors.WaitCursor;

                backgroundWorker.RunWorkerAsync();
            }
        }

        private bool ValidateEntries()
        {
            if (txtTemplatePath.Text == String.Empty)
            {
                MessageBox.Show("Please specify the template path.",
                    "Insufficient Information",
                MessageBoxButtons.OK,
                MessageBoxIcon.Error);
                return false;
            }

            if (txtNewTemplateName.Text == String.Empty)
            {
                MessageBox.Show("Please specify the template name.",
                    "Insufficient Information",
                MessageBoxButtons.OK,
                MessageBoxIcon.Error);
                return false;
            }

            if ((TemplateLocation)cmbTemplateLocation.SelectedValue == TemplateLocation.SQLServer)
            {
                if (cmbServer.Text == String.Empty)
                {
                    MessageBox.Show("Please specify the server name.",
                        "Insufficient Information",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
                    return false;
                }
                else
                {
                    try
                    {
                        SqlConnection connection = new SqlConnection(PrepareConnectionString());
                        connection.Open();
                        connection.Close();
                    }
                    catch (Exception e)
                    {
                        MessageBox.Show(e.Message,
                        "Insufficient Information",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
                        return false;

                    }
                }
            }
            else
            {
                if (File.Exists(txtTemplatePath.Text) == false)
                {
                    MessageBox.Show("Please specify the proper template path.",
                    "Insufficient Information",
                MessageBoxButtons.OK,
                MessageBoxIcon.Error);
                    return false;
                }
            }
            return true;
        }

        private string PrepareConnectionString()
        {
            // Prepare a connection string.
            SqlConnectionStringBuilder builder =
                new SqlConnectionStringBuilder();
            builder.DataSource = cmbServer.Text;
            if (cmbAuthentication.SelectedValue is int
                && (ServerAuthentication)cmbAuthentication.SelectedValue ==
                ServerAuthentication.WindowsAuthentication)
                builder.IntegratedSecurity = true;
            else
            {
                builder.IntegratedSecurity = false;
                builder.UserID = txtUserName.Text;
                builder.Password = txtPassward.Text;
            }

            builder.InitialCatalog = "master";

            return builder.ConnectionString;
        }

        #endregion
    }
}